#include "Protocol.hpp"
#include "Socket.hpp"

#include <iostream>
#include <unistd.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

void Usage(string proc)
{
    cout << proc << " serverport serverport" << endl;
}

int main(int argc , char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    string serverip = argv[1];
    uint16_t serverport = stoi(argv[2]);

    // 建立连接
    Socket* conn = new TcpSocket();
    if(!conn->BuildConnectSocketMethod(serverip,serverport))
        delete conn;

    // 设置随机数种子
    srand(time(nullptr) ^ getpid());
    
    string op_str("+-*/%!#");

    unique_ptr<Factory> factory = make_unique<Factory>();

    string responsestr;

    while(1)
    {
        // 1、构建请求
        int x = rand() % 200; // [0,199]
        usleep(rand()%500000);
        int y = rand() % 200; // [0,199]
        char op = op_str[rand()%op_str.size()];
        shared_ptr<Request> req = factory->BuildRequest(x,y,op);
        // 2、对请求进行序列化
        string requeststr;
        req->Serialize(&requeststr);
        string expression = requeststr + " = "; // 表达式
        // 3、添加自描述报头
        string send_request = EnCode(requeststr);
        // 4、发送请求
        conn->Send(send_request);
        // 5、接收响应
        while(conn->Recv(responsestr,1024))
        {
            // 6、对报文进行解析
            string message;
            if(!DeCode(responsestr,&message)) continue;
            // 7、反序列化
            shared_ptr<Response> resp = factory->BuildResponse();
            resp->Deserialize(message);
            // 8、得到结果
            cout << expression << resp->GetResult() << '[' << resp->GetCode() << ']' << endl;
            break;
        }
    }

    conn->CloseSockFd();
    delete conn;
    return 0;
}